package com.example.apple.lwb_json;

import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static android.R.attr.type;

/**
 * Created by apple on 17/3/21.
 */

public class JSONModel {
    Map<String,String> entityClasss;
    String completePackageName="";
    String firstLayerClassName ="";
    void setEntityClasss(Map<String,String>entityClasss){
        this.entityClasss=entityClasss;
    }
     Object initWithDictionary(JSONObject jsonObject,String completename,String objectname) {
         String object = completename+objectname;
         if (completePackageName.equals("")){
             completePackageName =completename;
         }
         if (firstLayerClassName.equals("")){
             firstLayerClassName =completename+objectname;
         }
         Log.e("Object:-->",object);
        try {
            Class c = Class.forName(object);
            Object yourObj = c.newInstance();
            Method methlist[] = obtainAllClassMethod(c);
            ArrayList<Map<String, Object>> arr = getFiledsInfo(yourObj);
            for (int i = 0; i < arr.size(); i++) {
                Map attributes = new HashMap<>();
                attributes = arr.get(i);
                if (attributes.get("type").equals("class java.lang.String")) {
                    String s = "set" + capitalizeTheFirstLetter(attributes.get("name").toString());
                    Method met = obtainSpecifiedClassMethod(methlist, s);
                    if (met != null) {
                        met = c.getMethod(s, new Class[]{String.class});
                        //获得参数Object
                        Object[] arguments = new Object[]{new String(jsonObject.getString(attributes.get("name").toString()))};
                        //执行方法
                        met.invoke(yourObj, arguments);
                    } else {
                        Log.e("此属性需要设置一个方法", attributes.get("name").toString() + ":" + s);
                    }
                } else if (attributes.get("type").equals("class java.util.ArrayList")) {
//                    JSONObject json2 =jsonObject.getJSONObject((String) attributes.get("name"));
                    ArrayList arrJson = obtainJSONObjectArrayElementKey(jsonObject);
                    String arrEntity = entityClasss.get((String) attributes.get("name"));
                   // JSONObject jsonObject1 = jsonObject.getJSONObject((String) attributes.get("name"));
                    ArrayList arrayList = new ArrayList();
                    if (judgeJsonarrayOrJsonObject(jsonObject)){
                        for (int i1 = 0; i1 < arrJson.size(); i1++) {

                            String arrjsonone = (String) arrJson.get(i1);
                            arrayList.add(initWithDictionary(jsonObject.getJSONObject(arrjsonone),completePackageName,arrEntity.toString().substring(6)));
                        }
                    }
                    String s = "set" + capitalizeTheFirstLetter(attributes.get("name").toString());
                    Method met = obtainSpecifiedClassMethod(methlist, s);
                    if (met != null) {
                      //  Object obj1 = initWithDictionary(jsonObject.getJSONObject(String.valueOf(attributes.get("name"))), attributes.get("type").toString().substring(6));

                        //获得参数Object
                        Object[] arguments = new Object[]{arrayList};
                        //执行方法
                        met.invoke(yourObj, arguments);
                    }else {
                        Log.e("此属性需要设置一个方法", attributes.get("name").toString() + ":" + s);
                    }
                } else if (!attributes.get("type").equals(firstLayerClassName)){
                    String s = "set" + capitalizeTheFirstLetter(attributes.get("name").toString());
                    Method met = obtainSpecifiedClassMethod(methlist, s);
                    if (met != null) {
                        Object obj1 = initWithDictionary(jsonObject.getJSONObject(String.valueOf(attributes.get("name"))),"",attributes.get("type").toString().substring(6));

                        //获得参数Object
                        Object[] arguments = new Object[]{obj1};
                        //执行方法
                        met.invoke(yourObj, arguments);
                    }else {
                        Log.e("此属性需要设置一个方法", attributes.get("name").toString() + ":" + s);
                    }
                };
              //  return yourObj;
            }
            return yourObj;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            Log.e("解析失败:", String.valueOf(e));
            return null;
        } catch (JSONException e) {
            e.printStackTrace();
            System.out.println("000000000000");
            return null;
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            System.out.println("1111111111");
        } catch (InstantiationException e) {
            e.printStackTrace();
            System.out.println("222222222");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            System.out.println("333333333");
        } catch (InvocationTargetException e) {
            e.printStackTrace();
            System.out.println("444444444");
        }
        return null;
    }
    /**
     * 获取类所有的方法
     * */
    private Method[]  obtainAllClassMethod(Class o){
        Method methlist[] = o.getDeclaredMethods();
    for (int i = 0; i < methlist.length; i++) {
        Method m = methlist[i];
    }
        return methlist;
    }
    /**
     * 获取类指定的方法
     * */
    private Method obtainSpecifiedClassMethod(Method [] methods,String spec){
       for (Method e :methods){
           if (e.getName().equals(spec)){
               return e;
           }
       }
       return null;
   }
    /**
     * 判断是否为
     * */
    boolean judgeJsonarrayOrJsonObject(JSONObject jsonObject){
        String jsonStr = jsonObject.toString();
        String[] jsonStrArr =jsonStr.split(":");
        if (jsonStrArr[1].substring(0,1).equals("{")){
            return true;
        }else {
            return false;
        }
    }
    /**
     * 首字母变大写
     * */
    private String capitalizeTheFirstLetter(String string){
        String s = string.substring(0,1).toUpperCase();
        String s2 = string.substring(1);
        return s+s2;
    }

    /**
     * 获取属性的类型、名字、值；
     * */
    private ArrayList getFiledsInfo(Object o){
        Field[] fields=o.getClass().getDeclaredFields();
        String[] fieldNames=new String[fields.length];
        ArrayList list = new ArrayList();
        Map infoMap=null;
        for(int i=0;i<fields.length;i++){
            infoMap = new HashMap();
            infoMap.put("type", fields[i].getType().toString());
            infoMap.put("name", fields[i].getName());
            infoMap.put("value", getFieldValueByName(fields[i].getName(), o));
            list.add(infoMap);
        }
        return list;
    }
   // 根据属性名获取属性值
    private Object getFieldValueByName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter, new Class[] {});
            Object value = method.invoke(o, new Object[] {});
            return value;
        } catch (Exception e) {
            Log.e(e.getMessage(), String.valueOf(e));
            return null;
        }

    }
    //获取给定jsonobject的数组元素
    private ArrayList<String> obtainJSONObjectArrayElementKey(JSONObject json){
        String jsonStr = (String) json.toString();
        jsonStr=jsonStr.substring(1,jsonStr.length()-1);
        int flog =0;
        String key =null;
        boolean takePrepareFlog=true;
        boolean takeFlog =false;
        ArrayList<String>arrKeys = new ArrayList<>();
        jsonStr=jsonStr.trim();
        String str2="";
            if(jsonStr != null && !"".equals(jsonStr)){

                for(int i=0;i<jsonStr.length();i++){
                    str2 = String.valueOf(jsonStr.charAt(i));
                    if(str2.equals("{")){
                        flog++;
                    }
                    if (str2.equals("}")){
                        flog--;
                    }

                    if (takeFlog==true&&str2.equals("\"")){
                        arrKeys.add(key);
                        takePrepareFlog=false;
                        takeFlog =false;
                    }
                    if (takePrepareFlog==true&&takeFlog==true){
                        key=key+str2;
                    }
                    if (flog==0&&takePrepareFlog==true&str2.equals("\"")){
                        key = new String();
                        takeFlog=true;
                    }
                    if (flog==0&&takePrepareFlog==false){
                        takePrepareFlog=true;
                    }
                }

            }
        return arrKeys;
    }
}
